#ifndef DNAMAP_H_INCLUDED
#define DNAMAP_H_INCLUDED

#include<stdio.h>
#include<string>
namespace dnamap
{
    const char basecode[] = "ATGC";
    const int codonlen = 3;
    const int codonnum = 64;
    const int alphalen = 99;
    const int dbaselen = 4;
    const int baselen = 2;
    const int dbasemask = 0x0f;
    const int basemask = 0x03;

    class nucleotidebase
    {
        protected:
            int codelookup(const char);                                     //from char to numeric base
            int dcodon2bcodon(const int);                                   //from degenerate to numeric
            int dcodelookup(const char);                                    //from char to degenerate
            int dcodonlookup(const int);                                    //from numeric codon to degenerate
            int bcode2dcode(const int);                                     //from numeric to degenerate base
    };

    class dnaseq: private nucleotidebase
    {
        private:
            std::string readframe[codonlen];                                    //Sequence in frame, numeric
            int seqlen, framelen;                                               //Sequence length, char format/numeric format
            int baselookup(const int);                                          //Return base at position X, numeric
        public:
            dnaseq();                                                           //Constructor
            dnaseq(const std::string);                                          //Constructor based on DNA sequence X
            dnaseq(const char*);                                                //Constructor based on DNA sequence X
            dnaseq(const std::string, const int);                               //Constructor, direct copy raw data
            ~dnaseq();                                                          //Destructor
            char base(const int);                                               //Return base at No. X, char
            void enter(const char*);                                            //Input char DNA sequence
            std::string nucleotide(const int, const int);                       //Return DNA sequence
            std::string getframe(const int);                                    //Return Reading Frame No. X, in numeric format
            std::string getframe(const int, const int);                         //Return reading frame from base A with length L, numeric
            int length();                                                       //Sequence Length
    };

    class sitelist
    {
        private:
            int len, pos;                                                       //Length, pointer
            int *list;                                                          //Site list
            const int stepspc;                                                  //Space
        public:
            int& operator[] (const unsigned int);
            sitelist(const sitelist&);
            sitelist(const int);
            sitelist& operator= (const sitelist&);
            ~sitelist();
            int length();
            void remove(const int);
            void push_back(const int);
    };

    class protrans: private nucleotidebase
    {
        private:
            char codon[codonnum];                                   //Codon translator
            unsigned short DegenerateCodon[codonnum];               //base to degenerate base
            unsigned short *anticodon[alphalen];                    //anticodon lookup
            int codoncount[alphalen];                               //codon num for each AA
        public:
            protrans(const char*);                                  //Read from file char
            ~protrans(){};
            std::string translate(std::string);                     //Translate a dna sequence
            sitelist synmut(std::string&, const char*);             //synonymous mutation
    };

    class restriction: private nucleotidebase
    {
        public:
            char* siteseq;                                          //site sequence, degenerate numeric
            char* sitename;                                         //site name, char
            char* sitestr;                                          //site sequence, dna
            int sitelen;                                            //site length
            restriction(const char*, const char*);                  //site sequence, site name
            ~restriction();
    };

}
#endif // DNAMAP_H_INCLUDED
